package com.lysj.admin.master.bussiness.company.company.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.extension.api.R;
import com.lysj.admin.master.bussiness.company.company.EmployeeConstant;
import com.lysj.admin.master.bussiness.company.company.domain.Employee;
import com.lysj.admin.master.bussiness.company.company.dto.EmployeeAddDto;
import com.lysj.admin.master.bussiness.company.company.dto.OpenIdAndKeyDTO;
import com.lysj.admin.master.bussiness.company.company.service.EmployeeService;
import com.lysj.admin.master.common.CommonConstant;
import com.lysj.admin.master.common.annotation.TokenInfo;
import com.lysj.admin.master.common.exception.BaseException;
import com.lysj.admin.master.common.json.JacksonUtil;
import com.lysj.admin.master.common.jwt.JwtUtil;
import com.lysj.admin.master.common.spring.base.BaseContent;
import com.lysj.admin.master.common.validation.annotation.Valid;
import com.lysj.admin.master.common.web.ParamUtil;
import com.lysj.admin.master.common.web.Resp;
import com.lysj.admin.master.common.web.RespUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.Map;

import static com.lysj.admin.master.common.CommonConstant.EMPLOYEE_ID_NAME;

/**
 * @author Created by zk on 2020-01-14 15:54
 * @description
 */
@Slf4j
@RestController
@RequestMapping("/company/employee")
public class EmployeeController extends BaseContent {

    private static final String APP_ID = "wxb47bce4e94ef8885";
    private static final String APP_KEY = "0498f7d2bf6b4ed1c4e36709adbfcf7f";
    private static final String AUTHOR_INFO_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code";

    @Resource
    private EmployeeService employeeService;

    @PostMapping("/login")
    public Resp login(String code) {
        final String sr = HttpUtil.get(StrFormatter.format(AUTHOR_INFO_URL, APP_ID, APP_KEY, code));
        final Map<String, String> map = JacksonUtil.toStringMap(sr);
        String errcode = String.valueOf(map.get("errcode") == null ? "" : map.get("errcode"));
        log.info("微信授权内容----->>>>" + sr);
        String openId;
        String key;
        if (ParamUtil.isBlank(errcode) || errcode.equals("0")) {
            openId = map.get("openid");
            key = map.get("session_key");
        } else {
            return RespUtil.error(Resp.ResStatus.PARAM_ERROR, map.get("errmsg"));
        }
        Employee employee = employeeService.findByOpenId(openId);
        //如果雇员不存在,创建一个
        if (null == employee) {
            employee = new Employee();
            employee.setOpenId(openId);
            employee.setIdCardConfirmStatus(Employee.IdCardConfirmStatus.REGISTER.getCode());
            employee.setBalance(BigDecimal.ZERO);
            employeeService.save(employee);
        }
//        OpenIdAndKeyDTO openIdAndKeyDTO = EmployeeConstant.EMPLOYEE_CODE_KEY_CACHE.get(employee.getId());
//        if (ParamUtil.isBlank(openIdAndKeyDTO)) {
//            openIdAndKeyDTO = new OpenIdAndKeyDTO(openId, key);
//            EmployeeConstant.EMPLOYEE_CODE_KEY_CACHE.put(employee.getId(), openIdAndKeyDTO);
//        }
        OpenIdAndKeyDTO openIdAndKeyDTO = new OpenIdAndKeyDTO(openId, key);
        EmployeeConstant.EMPLOYEE_CODE_KEY_CACHE.put(employee.getId(), openIdAndKeyDTO);
        //创建雇员token
        Map<String, Object> employeeMap = new HashMap<>(1);
        employeeMap.put(EMPLOYEE_ID_NAME, employee.getId());
        String token = JwtUtil.createToken(employee.getId(), openIdAndKeyDTO.getOpenId(), CommonConstant.EMPLOYEE_ISSUER, CommonConstant.ADMIN_TOKEN_EXPIRATION, employeeMap);
        //构建返回结果
        Map<String, Object> resultMap = new HashMap<>(2);
        resultMap.put("token", token);
        resultMap.put("idCardConfirmStatus", employee.getIdCardConfirmStatus());
        return RespUtil.success(resultMap);
    }


    /*
     * @author Created by drj on 2020/1/15 10:14
     * @Description :绑定手机号
     */
    @PostMapping("/bind_phone")
    public Resp bindPhone(String encryptData, String ivData, @TokenInfo(property = EMPLOYEE_ID_NAME) String employeeId) {
        //获取sessionKey
        final OpenIdAndKeyDTO openIdAndKeyDTO = EmployeeConstant.EMPLOYEE_CODE_KEY_CACHE.get(employeeId);
        if (ParamUtil.isBlank(openIdAndKeyDTO)) {
            return RespUtil.error(Resp.ResStatus.PARAM_ERROR, "系统错误，请重试");
        }

        String phoneInfo;
        try {
            phoneInfo = aESDecode(encryptData, ivData, openIdAndKeyDTO.getKey());
        } catch (Exception e) {
            log.error(e.toString());
            return RespUtil.error(Resp.ResStatus.PARAM_ERROR, "手机号码解析失败，请重试");
        }
        final Map<String, String> map = JacksonUtil.toStringMap(phoneInfo);
        String phone = map.get("purePhoneNumber");
        Employee employee = employeeService.getById(employeeId);
        employee.setPhone(phone);
        employee.setIdCardConfirmStatus(Employee.IdCardConfirmStatus.BINDPHONE.getCode());
        employeeService.saveOrUpdate(employee);
        return RespUtil.success("操作成功");
    }

    /*
     * @author Created by drj on 2020/1/15 10:41
     * @Description :上传身份证信息
     */
    @PostMapping("/upload_id_info")
    public Resp uploadIdInfo(@Valid EmployeeAddDto model, @TokenInfo(property = EMPLOYEE_ID_NAME) String employeeId) {
        Employee employee = employeeService.getById(employeeId);
        //进行属性拷贝
        BeanUtil.copyProperties(model, employee);
        employeeService.saveOrUpdate(employee);
        return RespUtil.success("操作成功");
    }

    /*
     * @author Created by drj on 2020/1/15 14:36
     * @Description:上传签名照片
     */
    @PostMapping("/upload_sign_info")
    public Resp uploadSignInfo(String signPhoto, @TokenInfo(property = EMPLOYEE_ID_NAME) String employeeId) {
        if (ParamUtil.isBlank(signPhoto)) {
            return RespUtil.error(Resp.ResStatus.PARAM_ERROR, "请上传签名照片");
        }
        Employee employee = employeeService.getById(employeeId);
        employee.setSignPhoto(signPhoto);
        employee.setIdCardConfirmStatus(Employee.IdCardConfirmStatus.UNCERTIFY.getCode());
        employeeService.saveOrUpdate(employee);
        return RespUtil.success("操作成功");
    }


    /*
     * @author Created by drj on 2020/1/15 14:41
     * @Description :显示员工个人信息
     */
    @GetMapping("/detail")
    public Resp detail(@TokenInfo(property = EMPLOYEE_ID_NAME) String employeeId) {
        return RespUtil.success(employeeService.getById(employeeId));
    }


    /**
     * Created by hgg on 2018/2/24.
     * <p>
     * 小程序AES解密
     */

    private String aESDecode(String encryptData, String ivData, String sessionKey) throws Exception {
        return decrypt(Base64.decodeBase64(sessionKey), Base64.decodeBase64(ivData), Base64.decodeBase64(encryptData));
    }

    private String decrypt(byte[] key, byte[] iv, byte[] encData) throws Exception {

        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");

        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

        return new String(cipher.doFinal(encData), StandardCharsets.UTF_8);

    }


}
